classdef TestDotsAllRemoteObjectManagers < TestDotsAllObjectManagers
    
    properties
        serverManager;
    end
    
    methods
        function self = TestDotsAllRemoteObjectManagers(name)
            self = self@TestDotsAllObjectManagers(name);
        end
        
        function setUp(self)
            self.setUp@dotsTestCase;
            
            % the "Testable" subclass is not really a singleton
            self.manager = dotsAllRemoteObjectManagersTestable.theObject;
            self.manager.openClientSocket;
            self.manager.name = 'client';
            
            self.serverManager = dotsAllRemoteObjectManagersTestable.theObject;
            self.serverManager.openServerSocket;
            self.serverManager.name = 'server';
            
            % let the managers be crosswired
            self.manager.counterpart = self.serverManager;
            self.serverManager.counterpart = self.manager;
        end
        
        function tearDown(self)
            self.tearDown@dotsTestCase;
            
            assertTrue(self.manager.transactionsClosed > 0, 'remote manager should have done some transactions');
            assertEqual(self.manager.transactionsPending, 0, 'remote manager should have finished all transactions');
            
            self.assertManagersAreEquivalent;
        end
        
        function assertManagersAreEquivalent(self)
            assertEqual(self.manager.managedObjects.length, ...
                self.serverManager.managedObjects.length, ...
                'client and server lists have different numbers of items');
            
            assertEqual(sort(self.manager.managedObjects.groups), ...
                sort(self.serverManager.managedObjects.groups), ...
                'client and server lists have different groups');
            
            groups = self.manager.managedObjects.groups;
            for ii = 1:length(groups)
                [clientObjects, clientUIDs] = self.manager.getGroup(groups{ii});
                [serverObjects, serverUIDs] = self.serverManager.getGroup(groups{ii});
                
                assertEqual(clientUIDs, serverUIDs, ...
                    sprintf('"%s" groups should have identical UIDs', groups{ii}))
            end
            
            [clientObjects, clientUIDs] = self.manager.getAll;
            [serverObjects, serverUIDs] = self.serverManager.getAll;
            for jj = 1:length(clientObjects)
                assertEqual(class(clientObjects{jj}), class(serverObjects{jj}), ...
                    sprintf('counterpart objects should have same class', groups{ii}))
                
                property = 'testProperty';
                assertEqual(clientObjects{jj}.(property), serverObjects{jj}.(property), ...
                    sprintf('counterpart objects should have matchine properties', groups{ii}))
            end
        end
        
        function testSelfTransactions(self)
            testValue = 'gorgonxola';
            self.manager.testProperty = testValue;
            assertEqual(self.manager.testProperty, ...
                self.serverManager.testProperty, ...
                'manager should have forwarded own property to serverManager');
            
            self.manager.testMethod(testValue);
            assertEqual(self.manager.testMethodResult, testValue, ...
                'manager should have called method on itsself');
            assertEqual(self.manager.testMethodResult, ...
                self.serverManager.testMethodResult, ...
                'manager should have called method on its counterpart');
        end
    end
end